package qc.module.demo.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.module.demo.dto.qzj.*;
import qc.module.demo.entity.Qzj;
import qc.module.demo.entity.enums.QzjHandleFlagEnum;
import qc.module.demo.mapper.QzjMapper;
import qc.module.demo.repository.QzjRepository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * QzjService
 *
 * @author QuCheng Tech
 */
@Service
public class QzjService {

    private QzjRepository repository;

    @Autowired
    public void setQzjRepository(QzjRepository repository) {
        this.repository = repository;
    }

    private IQzjBatchService batchService;

    @Autowired
    public void setBatchService(IQzjBatchService service) {
        this.batchService = service;
    }

    public String Save(QzjNewDataDto data) {
        if (data == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank((data.getStcd())))
            return QCUnifyReturnValue.Warn("STCD 不能为空");
        if (StringUtils.isBlank(data.getDatatype()))
            return QCUnifyReturnValue.Warn("datatype 不能为空");
        if (StringUtils.isBlank(data.getSensorid()))
            return QCUnifyReturnValue.Warn("sensorId 不能为空");
        if (StringUtils.isBlank(data.getTm()))
            return QCUnifyReturnValue.Warn("tm 不能为空");
        //DTO转换为Entity
        Qzj en = QzjMapper.QZJ_MAPPER.QzjDtoToQzj(data);

        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("保存失败");

        return QCUnifyReturnValue.Success();
    }

    public List<QzjDataDto> getNeedHandledList(Integer count) {
        List<QzjDataDto> result = null;

        //使用QueryWrapper，需要编写对应的字段名称，为字符串，不方便检查和自动分析错误
        //QueryWrapper<Qzj> wrapper=new QueryWrapper<>();
        //wrapper.eq("FLAG",0);
        //wrapper.orderByAsc("stcd");
        //wrapper.orderByAsc("datatype");
        //wrapper.orderByAsc("sensorid");
        //wrapper.orderByAsc("tm");
        //if (count>0)
        //wrapper.last("limit "+ count.toString());
        //List<Qzj> list= repository.selectList(wrapper);

        LambdaQueryWrapper<Qzj> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Qzj::getFLAG, QzjHandleFlagEnum.UN_DEFINE);
        wrapper.orderByAsc(Qzj::getStcd);
        wrapper.orderByAsc(Qzj::getDatatype);
        wrapper.orderByAsc(Qzj::getSensorid);
        wrapper.orderByAsc(Qzj::getTm);

        //如果有传入获取条数，使用limit
        if (count > 0)
            wrapper.last("limit " + count.toString());
        List<Qzj> list = repository.selectList(wrapper);

        if (list != null && list.size() > 0x0)
            result = QzjMapper.QZJ_MAPPER.toDtoList(list);

        return result;
    }

    public String reHandle(QzjRehandleDto rehandleDto) {
        if (rehandleDto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank((rehandleDto.getBeginTime())))
            return QCUnifyReturnValue.Warn("起始时间 不能为空");
        if (StringUtils.isBlank(rehandleDto.getEndTime()))
            return QCUnifyReturnValue.Warn("截止时间 不能为空");
        Date beginTime = DateUtil.parseDate(rehandleDto.getBeginTime());
        Date endTime = DateUtil.parseDate(rehandleDto.getEndTime());
        if (beginTime.after(endTime))
            return QCUnifyReturnValue.Warn("起始时间不能大于截止时间");

        LambdaUpdateWrapper<Qzj> wrapper = new LambdaUpdateWrapper<>();
        //修改flag列的值
        wrapper.set(Qzj::getFLAG, QzjHandleFlagEnum.UN_DEFINE);
        //wrapper.ge(Qzj::getTm,beginTime);
        //wrapper.le(Qzj::getTm,endTime);
        wrapper.between(Qzj::getTm, beginTime, endTime);
        if (!StringUtils.isBlank(rehandleDto.getStcd()))
            wrapper.eq(Qzj::getStcd, rehandleDto.getStcd());
        if (!StringUtils.isBlank(rehandleDto.getDatatype()))
            wrapper.eq(Qzj::getDatatype, rehandleDto.getDatatype());
        if (!StringUtils.isBlank(rehandleDto.getSensorId()))
            wrapper.eq(Qzj::getSensorid, rehandleDto.getSensorId());

        //通过实体类修改指定的列，需要实体类中的均为封装类型，基本数据类型有默认值，可能会出现修改非预期列的值
        //Qzj updateEntity = new Qzj();
        //updateEntity.setFLAG((byte) 0x0);

        repository.update(null, wrapper);//不需要判断受影响的行数，只要sql执行成功

        return QCUnifyReturnValue.Success();
    }

    public String setFlag(QzjUpdateFlagDto flagDto) {
        if (flagDto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        if (flagDto.getFlag() == null)
            return QCUnifyReturnValue.Warn("flag参数不能为空");
        if (flagDto.getId() == null)
            return QCUnifyReturnValue.Warn("id不能为空");

        LambdaUpdateWrapper<Qzj> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Qzj::getId, flagDto.getId());
        if (flagDto.getFlag())
            wrapper.set(Qzj::getFLAG, QzjHandleFlagEnum.SUCCESS);
        else
            wrapper.set(Qzj::getFLAG, QzjHandleFlagEnum.FAIL);
        //修改标记的同时修改处理时间
        wrapper.set(Qzj::getHANDLETM, DateUtil.getNowDate());

        if (repository.update(null, wrapper) < 0x1)
            return QCUnifyReturnValue.Warn("修改标记失败，未修改任何记录");

        return QCUnifyReturnValue.Success();
    }

    public List<QzjDataDto> query(QzjQueryConditionDto conditionDto) throws Exception {
        if (conditionDto == null)
            throw new QCPromptException("对象不能为空");
        if (StringUtils.isBlank((conditionDto.getBeginTime())))
            throw new QCPromptException("起始时间 不能为空");
        if (StringUtils.isBlank(conditionDto.getEndTime()))
            throw new QCPromptException("截止时间 不能为空");
        Date beginTime = DateUtil.parseDate(conditionDto.getBeginTime());
        Date endTime = DateUtil.parseDate(conditionDto.getEndTime());
        //转换出错时转换方法中不抛出异常，在此判断是否为null
        if (beginTime == null)
            throw new QCPromptException("转换后的起始时间 不能为空");
        if (endTime == null)
            throw new QCPromptException("转换后的截止时间 不能为空");
        if (beginTime.after(endTime))
            throw new QCPromptException("起始时间不能大于截止时间");

        LambdaQueryWrapper<Qzj> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(Qzj::getTm, beginTime, endTime);
        if (!StringUtils.isBlank(conditionDto.getStcd()))
            wrapper.like(Qzj::getStcd, conditionDto.getStcd());
        if (!StringUtils.isBlank(conditionDto.getDatatype()))
            wrapper.like(Qzj::getDatatype, conditionDto.getDatatype());
        if (conditionDto.getFlag() != null)
            wrapper.eq(Qzj::getFLAG, conditionDto.getFlag());

        List<Qzj> list = repository.selectList(wrapper);

        if (list != null && list.size() > 0x0)
            return QzjMapper.QZJ_MAPPER.toDtoList(list);

        return null;
    }

    public List<QzjDataDto> queryPartFields(QzjQueryConditionDto conditionDto) throws Exception {
        if (conditionDto == null)
            throw new QCPromptException("对象不能为空");
        if (StringUtils.isBlank((conditionDto.getBeginTime())))
            throw new QCPromptException("起始时间 不能为空");
        if (StringUtils.isBlank(conditionDto.getEndTime()))
            throw new QCPromptException("截止时间 不能为空");
        Date beginTime = DateUtil.parseDate(conditionDto.getBeginTime());
        Date endTime = DateUtil.parseDate(conditionDto.getEndTime());
        //转换出错时转换方法中不抛出异常，在此判断是否为null
        if (beginTime == null)
            throw new QCPromptException("转换后的起始时间 不能为空");
        if (endTime == null)
            throw new QCPromptException("转换后的截止时间 不能为空");
        if (beginTime.after(endTime))
            throw new QCPromptException("起始时间不能大于截止时间");

        LambdaQueryWrapper<Qzj> wrapper = new LambdaQueryWrapper<>();
        //测试指定查询字段，仅返回时间和值
        //wrapper.select(Qzj::getTm);
        //wrapper.select(Qzj::getValue);
        //不能分开写，必须使用数组形式在一次select方法中传入
        wrapper.select(Qzj::getTm, Qzj::getValue);

        wrapper.between(Qzj::getTm, beginTime, endTime);
        if (!StringUtils.isBlank(conditionDto.getStcd()))
            wrapper.like(Qzj::getStcd, conditionDto.getStcd());
        if (!StringUtils.isBlank(conditionDto.getDatatype()))
            wrapper.like(Qzj::getDatatype, conditionDto.getDatatype());
        if (conditionDto.getFlag() != null)
            wrapper.eq(Qzj::getFLAG, conditionDto.getFlag());

        List<Qzj> list = repository.selectList(wrapper);

        if (list != null && list.size() > 0x0)
            return QzjMapper.QZJ_MAPPER.toDtoList(list);

        return null;
    }

    public String batchSaveData(List<QzjNewDataDto> listDto) {
        if (listDto == null || listDto.size() < 0x1)
            return QCUnifyReturnValue.Warn("对象不能为空");

        List<Qzj> listEntitys = new ArrayList<>();

        for (QzjNewDataDto dto : listDto) {
            if (StringUtils.isBlank((dto.getStcd())))
                return QCUnifyReturnValue.Warn("STCD 不能为空");
            if (StringUtils.isBlank(dto.getDatatype()))
                return QCUnifyReturnValue.Warn("datatype 不能为空");
            if (StringUtils.isBlank(dto.getSensorid()))
                return QCUnifyReturnValue.Warn("sensorId 不能为空");
            if (StringUtils.isBlank(dto.getTm()))
                return QCUnifyReturnValue.Warn("tm 不能为空");

            //DTO转换为Entity
            Qzj en = QzjMapper.QZJ_MAPPER.toEntity(dto);
            en.setId(UUID.randomUUID().toString());
            //转换时间
            en.setTm(DateUtil.parseDate(dto.getTm()));
            //设置写入时间为当前时间
            en.setUPDATETM(DateUtil.getNowDate());
            //设置处理标记为默认值0，表示未处理
            en.setFLAG(QzjHandleFlagEnum.UN_DEFINE);

            listEntitys.add(en);
        }

        if (!batchService.saveBatch(listEntitys))
            return QCUnifyReturnValue.Warn("批量新增失败");

        return QCUnifyReturnValue.Success();
    }
}
